package com.lkl.spring.context;

import com.lkl.spring.annotation.LklController;
import com.lkl.spring.annotation.LklResponseBody;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Properties;

@SuppressWarnings("all")
public class LklDispatcherServlet extends HttpServlet {

    private LklClassPathApplicationContext app;
    private final String pre = "/";
    private final String suffix = ".jsp";

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String url = req.getRequestURI();

        String contextPath = this.getServletContext().getContextPath();

        String actionUrl = url.replaceAll(contextPath, "");

        Object obj = this.app.getHandlerMap().get(actionUrl);

        if ("".equals(actionUrl) || actionUrl == null || "/".equals(actionUrl)) {
            return;
        }

        if (obj == null) {
            System.out.println("未找到对应handler，走错误的处理器");
            resp.getWriter().print("未找到对应handler，走错误的处理器");
        }

        Method method = (Method) this.app.getHandlerMap().get(actionUrl);

        System.out.println("method.getClass(): " + method.getDeclaringClass());

        LklController lklController = method.getDeclaringClass().getAnnotation(LklController.class);


        Object returnObj = null;
        Object objController = app.getIoc().get(lklController.value());
        try {
            returnObj =  method.invoke(objController);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        System.out.println("请求url:" + url + ", 返回值：" + returnObj);

        //视图解析器
        viewResolve(resp, req ,method, returnObj);
    }

    /**
     * 视图解析器
     * 判断是跳转页面还是，直接返回json
     */
    private void viewResolve(HttpServletResponse response, HttpServletRequest request, Method method, Object result) throws ServletException, IOException {
        LklResponseBody lklResponseBody = method.getAnnotation(LklResponseBody.class);
        //表示是走 返回json的格式
        if (lklResponseBody != null) {
            response.setHeader("content-type","text/json;charset=UTF-8");
            try {
                response.getWriter().print(result);
            } catch (IOException e) {
                System.out.println("执行出错拉");
            }
            return;
        }

        //直接跳转页面
        response.setHeader("content-type","text/html;charset=UTF-8");
        String forwardUrl;
        if (result == null) {
            forwardUrl = "/index.jsp";
        }else {
            forwardUrl = pre + result.toString() + suffix;
        }

        request.getRequestDispatcher(forwardUrl).forward(request, response);
    }

    @Override
    public void init() {
        try {
            String path1 = "/WEB-INF/classes/resources/application.properties";
            System.out.println("容器启动开始执行加载初始化的servlet...");
            LklClassPathApplicationContext context = new LklClassPathApplicationContext();

            String realPath = this.getServletContext().getRealPath(path1);
            System.out.println("realPath："+realPath);
            System.out.println("contextPath："+this.getServletContext().getContextPath());
            InputStreamReader reader = new InputStreamReader(new FileInputStream(realPath),"UTF-8");

            Properties properties = new Properties();
            properties.load(reader);

            List<String> list = context.findClass(properties);
            context.newInstance(list);
            this.app = context;
        }catch (Exception e) {
            System.out.println("LklDispatcherServlet初始化失败.." + e);
        }
    }
}
